﻿using System;
using System.Threading.Tasks;

namespace Sunny.FrameDecoder;

/// <summary>
/// 字节帧参数
/// </summary>
public class ByteFrameParams
{
    /// <summary>
    /// 空参数
    /// </summary>
    public static ByteFrameParams Empty => new();

    /// <summary>
    /// 字节帧 - 长度参数
    /// </summary>
    /// <param name="length">长度</param>
    /// <returns>字节帧 - 长度参数</returns>
    public static LengthByteFrameParams LengthParams(int length) => new(length);

    /// <summary>
    /// 字节帧 - 标签、长度参数
    /// </summary>
    /// <param name="tag">标签</param>
    /// <param name="length">长度</param>
    /// <returns>字节帧 - 标签、长度参数</returns>
    public static TagLengthByteFrameParams TagLengthParams(byte[] tag, int length) => new(tag, length);
}

/// <summary>
/// 字节帧 - 长度参数
/// </summary>
public class LengthByteFrameParams : ByteFrameParams
{
    /// <summary>
    /// 长度
    /// </summary>
    public int Length { get; private set; }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="length">长度</param>
    public LengthByteFrameParams(int length)
    {
        Length = length;
    }
}

/// <summary>
/// 字节帧 - 标签、长度参数
/// </summary>
public class TagLengthByteFrameParams : LengthByteFrameParams
{
    /// <summary>
    /// 标签
    /// </summary>
    public byte[] Tag { get; private set; }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="tag">标签</param>
    /// <param name="length">长度</param>
    public TagLengthByteFrameParams(byte[] tag, int length) : base(length)
    {
        Tag = tag;
    }

    /// <summary>
    /// 标签值，Tag长度1时为Byte值，2时为小端字节序UShort值，4时为小端字节序UInt值，其余为-1
    /// </summary>
    public int TagValue => DecoderHelper.GetLengthValue(Tag);
}

/// <summary>
/// 字节帧结构
/// </summary>
public readonly struct ByteEventArgs
{
    /// <summary>
    /// 数据缓存
    /// </summary>
    public readonly byte[] Buffer;

    /// <summary>
    /// 仅数据
    /// </summary>
    public ReadOnlySpan<byte> Value => Buffer.AsSpan();

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="value"></param>
    public ByteEventArgs(byte[] value)
    {
        Buffer = value;
    }
}

/// <summary>
/// 字节帧结构
/// </summary>
public readonly struct ByteFrameEventArgs
{
    /// <summary>
    /// 数据缓存
    /// </summary>
    public readonly byte[] Buffer;

    /// <summary>
    /// 仅数据
    /// </summary>
    public ReadOnlySpan<byte> Value => Buffer.AsSpan(_valueStart, Math.Min(_valueLength, Buffer.Length - _valueStart));

    /// <summary>
    /// 除数据外，包括各种参数，例如分隔符、标签、数据头、数据尾部等
    /// </summary>
    public ReadOnlySpan<byte> Body => Buffer.AsSpan();

    /// <summary>
    /// 解码器
    /// </summary>
    public readonly BaseByteFrameDecoder Decoder;

    /// <summary>
    /// 参数
    /// </summary>
    public readonly ByteFrameParams Params;

    private readonly int _valueStart;
    private readonly int _valueLength;

    /// <summary>
    /// 数据起始
    /// </summary>
    public int ValueStart => _valueStart;

    /// <summary>
    /// 数据长度
    /// </summary>
    public int ValueLength => _valueLength;

    /// <summary>
    /// 是否解码帧
    /// </summary>
    public bool IsDecoderFrame => Decoder != null;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="decoder">解码器</param>
    /// <param name="frameParams"></param>
    /// <param name="buffer">除数据外，包括各种参数，例如分隔符、标签、数据头、数据尾部等</param>
    public ByteFrameEventArgs(BaseByteFrameDecoder decoder, ByteFrameParams frameParams, byte[] buffer) :
        this(decoder, frameParams, 0, buffer.Length, buffer)
    {
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="decoder">解码器</param>
    /// <param name="frameParams"></param>
    /// <param name="valueLength">数据起始</param>
    /// <param name="valueStart">数据长度</param>
    /// <param name="buffer">除数据外，包括各种参数，例如分隔符、标签、数据头、数据尾部等</param>
    public ByteFrameEventArgs(BaseByteFrameDecoder decoder, ByteFrameParams frameParams, int valueStart, int valueLength, byte[] buffer)
    {
        Buffer = buffer;
        Decoder = decoder;
        Params = frameParams;
        _valueStart = valueStart;
        _valueLength = valueLength;
    }
}

/// <summary>
/// 字节数组数据事件类
/// </summary>
/// <param name="sender">对象</param>
/// <param name="e">字节数组数据事件类</param>
public delegate void OnByteFrameArgs(object sender, ByteFrameEventArgs e);

/// <summary>
/// 字节数组数据事件类
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <returns></returns>
public delegate Task OnByteFrameAsyncArgs(object sender, ByteFrameEventArgs e);

/// <summary>
/// 字节帧对象
/// </summary>
public class ByteFrame
{
    /// <summary>
    /// 仅数据
    /// </summary>
    public byte[] Value { get; }

    /// <summary>
    /// 除数据外，包括各种参数，例如分隔符、标签、数据头、数据尾部等
    /// </summary>
    public byte[] Body { get; }

    /// <summary>
    /// 解码器
    /// </summary>
    public BaseByteFrameDecoder Decoder { get; }

    /// <summary>
    /// 参数
    /// </summary>
    public ByteFrameParams Params { get; }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="e">字节帧结构</param>
    public ByteFrame(ByteFrameEventArgs e)
    {
        Decoder = e.Decoder;
        Params = e.Params;
        Value = e.Value.ToArray();
        Body = e.Body.ToArray();
    }
}